package org.muninn.niagara.structures;

import javax.baja.bacnet.BBacnetDevice;
import javax.baja.naming.BOrd;
import javax.baja.sys.BComponent;
import javax.baja.sys.BObject;

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class BPointTree extends BObject
{
  private BPointTreeNode[] children  = new BPointTreeNode[64];
  private BComponent root = null;

  public BPointTree() { new BPointTree("station:|slot:/Drivers"); }

  public BPointTree(String ord) { new BPointTree(BOrd.make(ord).resolve().getComponent()); }
  
  public BPointTree(BComponent start) { root = start; construct(start); }

  public BComponent getRoot() { return this.root; }

  public void construct(BComponent comp)
  {
    if (comp == null) return;

    if (comp instanceof BBacnetDevice)
      this.add(new BControllerNode(comp));
    
    else
    {
      BComponent[] temp = comp.getChildComponents();
      for (int i = 0; i < temp.length; i++)
        this.construct(temp[i]);
    }
  }

  public BControllerNode[] getControllersLike(String search)
  {
    BControllerNode[] cont = new BControllerNode[this.children.length];
    search.replaceAll("x", "\\\\d+");
    search = search + "\\d*";
    Pattern pat = Pattern.compile(search);
    
    for (int i = 0, k = 0; i < this.children.length; i++)
    {
      Matcher match = pat.matcher(children[i].name);
      boolean found = false;
      while (match.find()) { found = true; }
      if (found)
        cont[k] = (BControllerNode) children[i];
    }
    
    return cont;
  }
  
  public BControllerNode getController(String name)
  {
    for (int i = 0; i < this.children.length; i++)
    {
      if (this.children[i].name.equals(name))
        return (BControllerNode) this.children[i];
    }
    return null;
  }
  
  public BControllerNode[] gettControllerPoints(String name)
  {
    BControllerNode temp = (BControllerNode) getController(name);
    
    if (temp != null)
      return (BControllerNode[]) temp.children;
    else
      return null;
  }
  
  public BControllerNode[] getAllControllers() { return (BControllerNode[]) this.children; }
  
  public void add(BPointTreeNode node)
  {
    for (int i = 0; i < children.length; i++)
    {
      if (children[i] == null)
      {
        children[i] = node;
        return;
      }
    }

    BPointTreeNode[] temp = new BPointTreeNode[children.length * 2];
    for (int i = 0; i < children.length; i++)
      temp[i] = children[i];

    temp[children.length] = node;
    children = temp;
  }
}
